//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_CONFIG_TYPES_H
#define _UX_CONFIG_TYPES_H

#include <Includes.h>

namespace Engine
{
namespace ConfigTypes
{
	
	namespace e_config_object
	{
		typedef UXTypes::uint8	type;

		enum enum_type
		{
			UNKNOWN		= 0,
			FIELD,
			ARRAY,
			ENUM,
			CONSTANT,
			STRUCT,		// binary array

			VALUE,
			OBJECT,
			STRING
		};
	}

	namespace e_config_event
	{
		typedef UXTypes::uint8	type;

		enum enum_type
		{
			OBJ_CREATE	= 0x01,

		};
	}

	class CConfigBaseType;
	struct TConfigObjConstructor;


	typedef tree< CConfigBaseType *, TConfigObjConstructor>		config_tree_t;
	typedef config_tree_t::iterator								config_node_t;
	typedef config_tree_t::const_iterator						config_const_node_t;

	typedef bool (CALLBACK *POnCreateObjProc_t)(void *&pParam, void *pParametr);



	//
	// Config Base Type
	//

	class CConfigBaseType
	{
	protected:
		string			_sName;
		config_node_t	_pNode;
		int				_iRefCount;

		const e_config_object::type
						_eType;

	public:
		CConfigBaseType(config_node_t pParent, e_config_object::type eType);
		CConfigBaseType(config_node_t pParent, const char *pName, e_config_object::type eType);
		virtual ~CConfigBaseType();

		bool Free();

		bool SetName(const char *pName);
		void AddRef()										{ ++_iRefCount; }

		bool Copy(config_const_node_t pFields);
		bool CopyObj(config_const_node_t pFields);
		static void s_RecursiveCopyFields(config_node_t pNode, config_const_node_t pFields);

		virtual bool SetParams(const char *pParams)	{ return false; }

		const string &		GetName()	const	{ return _sName; }
		config_node_t		GetNode()	const	{ return _pNode; }

		e_config_object::type	GetType()	const	{ return _eType; }
	};
	

	//
	// Config Object Tree Constructor
	//

	struct TConfigObjConstructor
	{
		static void CreateDefault(CConfigBaseType *&e)					{ e = nullptr; }
		static void Create(CConfigBaseType *&e)							{}
		static void Destroy(CConfigBaseType *&e)						{ if ( e != nullptr ) e->Free(); }
		static void Copy(CConfigBaseType *&from, CConfigBaseType *&to)	{ to = from; }
	};



	//
	// Config Filed Value Type
	//

	class CConfigValueType : public CConfigBaseType
	{
	protected:
		union
		{
			double	_dValue;
			float	_fValue;
			int64	_i64Value;
			int32	_iValue;
			bool	_bValue;
			char	_aBuf[8];
		};
		e_value::type	_eValType;

	public:
		CConfigValueType(config_node_t pParent, const char *pName);
		CConfigValueType(const CConfigValueType &cObj, config_node_t pParent, const char *pName);
		virtual ~CConfigValueType();

		bool SetValue(const char *pValue, uint uLength, uint *pErrorPos = nullptr);
		bool SetBValue(bool bValue);
		
		bool CopyValue(CConfigBaseType *pObj, bool bInc = false);
		void SetDefault();

		void			GetValue(string &str)	const;
		const void *	GetValue()				const		{ return _aBuf; }
		e_value::type	GetValueType()			const		{ return _eValType; }
	};



	//
	// Config Object Type
	//

	class CConfigObjectType : public CConfigBaseType
	{
	protected:
		string		_sParams;
		bool		_bInitList;

	public:
		CConfigObjectType(config_node_t pParent);
		virtual ~CConfigObjectType();

		bool	IsInitList()	const	{ return _bInitList; }
		void	SetInitList(bool bIL)	{ _bInitList = bIL; }

		virtual bool	SetParams(const char *pParams);
		const char *	GetParams()  const	{ return _sParams.cstr(); }
		const string &	GetParamsS() const	{ return _sParams; }
	};



	//
	// Config String Type
	//

	class CConfigStringType : public CConfigBaseType
	{
	protected:
		string	_sValue;

	public:
		CConfigStringType(config_node_t pParent, const char *pName);
		CConfigStringType(const CConfigStringType &cObj, config_node_t pParent, const char *pName);
		virtual ~CConfigStringType();
		
		bool SetValue(const char *pValue, uint uLength);

		const string & GetStr()  const	{ return _sValue; }
		const char	 * GetCstr() const	{ return _sValue.cstr(); }
	};


	bool CreateType(CConfigBaseType *pObj, config_node_t pParent, const char *pName, CConfigBaseType *&pNewObj);

//-------------------------------------------------------------------

}	// ConfigTypes
}	// Engine

#endif	// _UX_CONFIG_TYPES_H